<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app1" class="testapp1"></div>
  <div id="app2"></div>
  <input type="text" value="foo" id="my-input" class="my-class"/>
<script>
  function createRenderer1() {
    function render(vnode, container) {
      console.log(container)
      if(vnode) {
        //新 vnode 存在，将其与旧的 vnode 一起穿给 path 函数进行更新
        path(container._vnode, vnode, container)
      } else {
        if(container._vnode) {
          //旧的vnode存在，新的不存在，说明是卸载操作，只需将container的DOM清空
          container.innerHTML = ''
        }
      }
      //将vnode存储到container._vnode中，即后续渲染的旧的vnode
      container._vnode = vnode
    }

    function path(n1, n2, container) {
      //如果n1不存在，意味着是初次挂载
      if(!n1) {
        mountElement(n2, container)
      } else {
        //n1存在，意味着需要更新dom,暂时省略
      }
    }

    function mountElement(vnode, container) {
      const el = document.createElement(vnode.type)
      if(typeof vnode.children === 'string') {
        el.textContent = vnode.children
      }
      container.appendChild(el)
    }

    return {
      render
    }
  }

  const vnode1 = {
    type: 'h1',
    children: '以浏览器为渲染平台'
  }
  const renderer1 = createRenderer1()
  renderer1.render(vnode1, document.getElementById('app1'))


  function createRenderer(options) {
    const {createElement, setElementText, insert} = options

    function render(vnode, container) {
      if(vnode) {
        //新 vnode 存在，将其与旧的 vnode 一起穿给 path 函数进行更新
        path(container._vnode, vnode, container)
      } else {
        if(container._vnode) {
          //旧的vnode存在，新的不存在，说明是卸载操作，只需将container的DOM清空
          container.innerHTML = ''
        }
      }
      //将vnode存储到container._vnode中，即后续渲染的旧的vnode
      container._vnode = vnode
    }

    function path(n1, n2, container) {
      //如果n1不存在，意味着是初次挂载
      if(!n1) {
        mountElement(n2, container)
      } else {
        //n1存在，意味着需要更新dom,暂时省略
      }
    }

    function mountElement(vnode, container) {
      const el = createElement(vnode.type)
      if(typeof vnode.children === 'string') {
        setElementText(el, vnode.children)
      }
      insert(el, container)
    }

    return {
      render
    }
  }
  const vnode2 = {
    type: 'h2',
    children: '设计通用渲染器'
  }
  const render2 = createRenderer({
    createElement(tag) {
      return document.createElement(tag)
    },
    setElementText(el, text) {
      el.textContent = text
    },
    insert(el, parent, anchor = null) {
      parent.insertBefore(el, anchor)
    }
  })
  render2.render(vnode2, document.getElementById('app2'))

  const vnode3 = {
    type: 'h3',
    children: 'hello'
  }
  const render3 = createRenderer({
    createElement(tag) {
      console.log(`创建了${tag}元素`)
      return {tag}
    },
    setElementText(el, text) {
      console.log(`设置了${JSON.stringify(el)} 的文本的内容 ${text}`)
      el.textContent = text
    },
    insert(el, parent, anchor = null) {
      console.log(`将${JSON.stringify(el)} 添加到${JSON.stringify(parent)}下`)
      parent.children = el
    }
  })
  render3.render(vnode3, {type:'root'})
</script>
</body>

</html>